package cc.shacocloud.mirage.restful.bind.support;

import cc.shacocloud.mirage.restful.HttpRequest;
import cc.shacocloud.mirage.restful.bind.annotation.RequestHeader;
import cc.shacocloud.mirage.restful.http.HttpHeaderMap;
import cc.shacocloud.mirage.utils.MethodParameter;
import cc.shacocloud.mirage.utils.Utils;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * 解析{@link RequestHeader} 注解的方法参数。
 * <p>
 * 支持三种方法参数定义类型：
 * <li>MultiMap类型，即当前请求的所有请求头{@link HttpHeaderMap}</li>
 * <li>List类型，即当前请求头指定名称的所有值</li>
 * <li>其他，即当前请求头指定名称的第一个值</li>
 */
public class RequestHeaderMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver {
    
    @Override
    public boolean supportsParameter(@NotNull MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestHeader.class);
    }
    
    @Override
    protected NamedValueInfo createNamedValueInfo(@NotNull MethodParameter parameter) {
        RequestHeader ann = parameter.getParameterAnnotation(RequestHeader.class);
        if (ann != null) return new HeaderNamedValueInfo(ann);
        
        throw new IllegalStateException("不支持处理当前方法，请先执行 supportsParameter 方法进行判断：" + Utils.methodDescription(parameter.getDeclaringClass(), parameter.getMethod()));
    }
    
    @Override
    protected Future<Object> resolveName(String name, @NotNull MethodParameter parameter, @NotNull HttpRequest request) {
        
        HttpHeaderMap headers = request.headers();
        
        Class<?> parameterType = parameter.getParameterType();
        
        // MultiMap 为当前所有请求头
        if (MultiMap.class.isAssignableFrom(parameterType)) {
            return Future.succeededFuture(headers);
        }
        
        // List 为指定名称请求头的所有值
        if (List.class.isAssignableFrom(parameterType)) {
            return Future.succeededFuture(headers.getAll(name));
        }
        
        // 其他 则为指定名称请求头的第一个值
        return Future.succeededFuture(headers.get(name));
    }
    
    private static class HeaderNamedValueInfo extends NamedValueInfo {
        
        public HeaderNamedValueInfo(@NotNull RequestHeader annotation) {
            super(annotation.name(), annotation.required(), annotation.defaultValue());
        }
        
        
    }
}
